package py.com.alfa.escriba.gui.rest.services.resttemplate;

import java.io.IOException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;

import py.com.alfa.escriba.gui.config.EscribaConfigApplicationContextProvider;
import py.com.alfa.escriba.gui.dto.admin.BarrioDTO;
import py.com.alfa.escriba.gui.dto.admin.DepartamentoDTO;
import py.com.alfa.escriba.gui.dto.admin.DistritoDTO;
import py.com.alfa.escriba.gui.dto.admin.FormulariosDTO;
import py.com.alfa.escriba.gui.dto.admin.LocalidadDTO;
import py.com.alfa.escriba.gui.dto.admin.NaturalezasDTO;
import py.com.alfa.escriba.gui.dto.admin.PaisDTO;
import py.com.alfa.escriba.gui.dto.admin.TabRefDTO;
import py.com.alfa.escriba.gui.dto.gestion.MonedasDTO;
import py.com.alfa.escriba.gui.rest.Headers;
import py.com.alfa.escriba.gui.rest.services.ReferenciaService;
import py.com.alfa.escriba.gui.services.Services;
import py.com.alfa.escriba.gui.utils.ObjectUtils;
import py.com.sif.rest.client.spring.request.ClientRequestBuilder;

@SuppressWarnings({ "unchecked"})
public class ReferenciaServiceClient implements ReferenciaService {

	private Logger log = LoggerFactory.getLogger(getClass());
	
	public ReferenciaServiceClient() {}

	@Override
	public List<DepartamentoDTO> obtenerDepartamentos() throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		ResponseEntity<DepartamentoDTO[]> response = (ResponseEntity<DepartamentoDTO[]>) request.exchange(LIST_DEPARTAMENTOS, HttpMethod.GET, DepartamentoDTO[].class);
		log.info("OK - obtenerDepartamentos");
		List<DepartamentoDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public void crearDepartamento(DepartamentoDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<DepartamentoDTO> response = (ResponseEntity<DepartamentoDTO>) request.exchange(CREA_DEPARTAMENTO, HttpMethod.POST, DepartamentoDTO.class);
		log.info("OK - crearDepartamento");
		DepartamentoDTO result = response.getBody();
		dto.setId(result.getId());
	}

	@Override
	public DepartamentoDTO actualizarDepartamento(DepartamentoDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<DepartamentoDTO> response = (ResponseEntity<DepartamentoDTO>) request.exchange(UPD_DEPARTAMENTO, HttpMethod.PUT, DepartamentoDTO.class);
		log.info("OK - actualizarDepartamento");
		DepartamentoDTO result = response.getBody();
		return result;
	}

	@Override
	public void eliminarDepartamento(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
	    if(!ObjectUtils.isEmpty(id))
	        request.addHeader(Headers.ID_DEPARTAMENTO, id.toString());
	    	    
	    request.exchange(DEL_DEPARTAMENTO, HttpMethod.DELETE, null);
		log.info("OK - eliminarDepartamento");
	}

	@Override
	public List<DistritoDTO> obtenerDistritos(Long idDepartamento) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("idDepartamento", idDepartamento.toString());
		ResponseEntity<DistritoDTO[]> response = (ResponseEntity<DistritoDTO[]>) request.exchange(LIST_DISTRITOS, HttpMethod.GET, DistritoDTO[].class);
		log.info("OK - obtenerDistritos");
		List<DistritoDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public void crearDistrito(DistritoDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<DistritoDTO> response = (ResponseEntity<DistritoDTO>) request.exchange(CREA_DISTRITO, HttpMethod.POST, DistritoDTO.class);
		log.info("OK - crearDistrito");
		DistritoDTO result = response.getBody();
		dto.setId(result.getId());
	}

	@Override
	public DistritoDTO actualizarDistrito(DistritoDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<DistritoDTO> response = (ResponseEntity<DistritoDTO>) request.exchange(UPD_DISTRITO, HttpMethod.PUT, DistritoDTO.class);
		log.info("OK - actualizarDepartamento");
		DistritoDTO result = response.getBody();
		return result;
	}

	@Override
	public void eliminarDistrito(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
	    if(!ObjectUtils.isEmpty(id))
	        request.addHeader(Headers.ID_DISTRITO, id.toString());
	    	    
	    request.exchange(DEL_DISTRITO, HttpMethod.DELETE, null);
		log.info("OK - eliminarDistrito");
	}

	@Override
	public List<BarrioDTO> obtenerBarrios(Long idDistrito) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("idDistrito", idDistrito.toString());
		ResponseEntity<BarrioDTO[]> response = (ResponseEntity<BarrioDTO[]>) request.exchange(LIST_BARRIOS, HttpMethod.GET, BarrioDTO[].class);
		log.info("OK - obtenerDistritos");
		List<BarrioDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public void crearBarrio(BarrioDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<BarrioDTO> response = (ResponseEntity<BarrioDTO>) request.exchange(CREA_BARRIO, HttpMethod.POST, BarrioDTO.class);
		log.info("OK - crearBarrio");
		BarrioDTO result = response.getBody();
		dto.setId(result.getId());
	}

	@Override
	public BarrioDTO actualizarBarrio(BarrioDTO dto) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addBody(dto);
		ResponseEntity<BarrioDTO> response = (ResponseEntity<BarrioDTO>) request.exchange(UPD_BARRIO, HttpMethod.PUT, BarrioDTO.class);
		log.info("OK - actualizarBarrio");
		BarrioDTO result = response.getBody();
		return result;
	}

	@Override
	public void eliminarBarrio(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
	    if(!ObjectUtils.isEmpty(id))
	        request.addHeader(Headers.ID_BARRIO, id.toString());
	    	    
	    request.exchange(DEL_BARRIO, HttpMethod.DELETE, null);
		log.info("OK - eliminarBarrio");
	}

	@Override
	public LocalidadDTO obtenerLocalidad(String idDepartamento) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("idDepartamento", idDepartamento);
		ResponseEntity<LocalidadDTO> response = (ResponseEntity<LocalidadDTO>) request.exchange(LOCALIDAD, HttpMethod.GET, LocalidadDTO.class);
		log.info("OK - obtenerDistritos");
		LocalidadDTO result = response.getBody();
		return result;
	}

	@Override
	public DepartamentoDTO obtenerDepartamento(String idDepartamento) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("idDepartamento", idDepartamento);
		ResponseEntity<DepartamentoDTO> response = (ResponseEntity<DepartamentoDTO>) request.exchange(GET_DEPARTAMENTO, HttpMethod.GET, DepartamentoDTO.class);
		log.info("OK - obtenerDepartamento {}", idDepartamento);
		DepartamentoDTO result = response.getBody();
		return result;
	}

	@Override
	public DistritoDTO obtenerDistrito(Long idDistrito) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("idDistrito", idDistrito.toString());
		ResponseEntity<DistritoDTO> response = (ResponseEntity<DistritoDTO>) request.exchange(GET_DISTRITO, HttpMethod.GET, DistritoDTO.class);
		log.info("OK - obtenerDistrito {}", idDistrito);
		DistritoDTO result = response.getBody();
		return result;
	}

	@Override
	public List<TabRefDTO> obtenerTablaReferencia(String tabla) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("tabla", tabla);
		ResponseEntity<TabRefDTO[]> response = (ResponseEntity<TabRefDTO[]>) request.exchange(LIST_TABREF, HttpMethod.GET, TabRefDTO[].class);
		log.info("OK - obtenerTablaReferencia {}", tabla);
		List<TabRefDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public List<PaisDTO> listPaises() throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		ResponseEntity<PaisDTO[]> response = (ResponseEntity<PaisDTO[]>) request.exchange(LIST_PAISES, HttpMethod.GET, PaisDTO[].class);
		log.info("OK - listPaises");
		List<PaisDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public PaisDTO paisById(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("id", id.toString());
		ResponseEntity<PaisDTO> response = (ResponseEntity<PaisDTO>) request.exchange(PAIS_BY_ID, HttpMethod.GET, PaisDTO.class);
		log.info("OK - paisById {}", id);
		PaisDTO result = response.getBody();
		return result;
	}

	@Override
	public PaisDTO paisBycodigo(String codigo) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("codigo", codigo);
		ResponseEntity<PaisDTO> response = (ResponseEntity<PaisDTO>) request.exchange(PAIS_BY_ID, HttpMethod.GET, PaisDTO.class);
		log.info("OK - paisBycodigo {}", codigo);
		PaisDTO result = response.getBody();
		return result;
	}

	@Override
	public List<MonedasDTO> listMonedas() throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		ResponseEntity<MonedasDTO[]> response = (ResponseEntity<MonedasDTO[]>) request.exchange(LIST_MONEDAS, HttpMethod.GET, MonedasDTO[].class);
		log.info("OK - listMonedas ");
		List<MonedasDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public MonedasDTO showMonedas(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("id", id.toString());
		ResponseEntity<MonedasDTO> response = (ResponseEntity<MonedasDTO>) request.exchange(MB_MONEDAS, HttpMethod.GET, MonedasDTO.class);
		log.info("OK - showMonedas ");
		MonedasDTO result = response.getBody();
		return result;
	}

	@Override
	public List<NaturalezasDTO> listNaturalezas() throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		ResponseEntity<NaturalezasDTO[]> response = (ResponseEntity<NaturalezasDTO[]>) request.exchange(LIST_NATURALEZAS, HttpMethod.GET, NaturalezasDTO[].class);
		log.info("OK - listNaturalezas ");
		List<NaturalezasDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public NaturalezasDTO showNaturalezas(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("id", id.toString());
		ResponseEntity<NaturalezasDTO> response = (ResponseEntity<NaturalezasDTO>) request.exchange(MB_NATURALEZAS, HttpMethod.GET, NaturalezasDTO.class);
		log.info("OK - showNaturalezas ");
		NaturalezasDTO result = response.getBody();
		return result;
	}

	@Override
	public List<FormulariosDTO> listFormularios() throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		ResponseEntity<FormulariosDTO[]> response = (ResponseEntity<FormulariosDTO[]>) request.exchange(LIST_FORMULARIOS, HttpMethod.GET, FormulariosDTO[].class);
		log.info("OK - listFormularios ");
		List<FormulariosDTO> result = request.getArrayAsList(response.getBody());
		return result;
	}

	@Override
	public FormulariosDTO showFormularios(Long id) throws IOException {
		GenericApplicationContext ctx = (GenericApplicationContext) EscribaConfigApplicationContextProvider.getContext();
		ClientRequestBuilder request = (ClientRequestBuilder) ctx.getBean(Services.REST_CLIENT);
		request.addParam("id", id.toString());
		ResponseEntity<FormulariosDTO> response = (ResponseEntity<FormulariosDTO>) request.exchange(MB_FORMULARIOS, HttpMethod.GET, FormulariosDTO.class);
		log.info("OK - showFormularios ");
		FormulariosDTO result = response.getBody();
		return result;
	}

}
